package com.next

import grails.converters.JSON
import grails.gorm.transactions.Transactional
import groovy.json.JsonOutput
import groovy.sql.Sql
import org.springframework.security.access.annotation.Secured

import java.text.DecimalFormat
import java.text.SimpleDateFormat
import org.grails.web.util.WebUtils

/*@Transactional(readOnly = true)*/

class AppOpportunityController
{
    static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]

    def opportunityService
    def appOpportunityService
    //    def liquidityRiskReportService
    def opportunityNotificationService
    def contactService
    def propertyValuationProviderService
    def dataSource
    def fileServerService
    def componentService
    //云丛网贷借款接口
    @Secured(['permitAll'])
    /*@Transactional*/
    // def appCreateOpportunity1()
    // {
    //     def json = request.JSON
    //     println "************************* appCreateOpportunity1 ***************************"
    //     println json
    //     def opportunity = new Opportunity()
    //     //金额loanAmount
    //     def loanAmount = json['loanAmount']
    //     //期限loanDuration
    //     def loanDuration = json['loanDuration']
    //     //用途loanUsage
    //     def loanUsage = json['loanUsage']
    //     //还款方式principalPaymentMethod
    //     def principalPaymentMethod = json['principalPaymentMethod']
    //     //银行卡号
    //     def numberOfAccount = json['numberOfAccount']
    //     //银行名称
    //     def bankName = json['bankName']
    //     // 银行账号名
    //     def name = json['name']
    //     def sessionId = json["sessionId"]
    //     if (loanAmount)
    //     {
    //         opportunity.loanAmount = loanAmount.toDouble()
    //         opportunity.requestedAmount = loanAmount.toDouble()
    //     }
    //     if (loanDuration)
    //     {
    //         opportunity.loanDuration = loanDuration.toInteger()
    //     }
    //     if (loanAmount)
    //     {
    //         opportunity.loanUsage = loanUsage
    //     }
    //     if (principalPaymentMethod)
    //     {
    //         opportunity.principalPaymentMethod = PrincipalPaymentMethod.findByName(principalPaymentMethod)
    //     }
    //     Contact contact = Contact.findByAppSessionId(sessionId)
    //     println "contact:  " + contact
    //     opportunity.user = contact?.user
    //     opportunity.account = contact?.user?.account
    //     opportunity.contact = contact
    //     opportunity.lender = contact
    //
    //
    //     def stage = OpportunityStage.findByName("基础材料已提供")
    //     opportunity.stage = stage
    //     opportunity.type = OpportunityType.findByCode("01")
    //
    //     // 银行卡opportunity.bankAccounts
    //     def OpportunityBankAccount = new OpportunityBankAccount()
    //     OpportunityBankAccount.type = OpportunityBankAccountType.findByName("收款账号")
    //     def bankAccount = new BankAccount()
    //     if (numberOfAccount)
    //     {
    //         bankAccount.numberOfAccount = numberOfAccount
    //     }
    //     if (bankName)
    //     {
    //         bankAccount.bank = Bank.findByName(bankName)
    //     }
    //     if (name)
    //     {
    //         bankAccount.name = name
    //     }
    //     //        bankAccount.name=contact.fullName
    //     bankAccount.cellphone = "15801173559"
    //     bankAccount.certificateType = ContactIdentityType.findByName("个人居民身份证")
    //     bankAccount.numberOfCertificate = "420117199875482634"
    //     bankAccount.paymentChannel = PaymentChannel.findByName("广银联")
    //
    //     if (bankAccount.validate())
    //     {
    //         bankAccount.save flush: true
    //         OpportunityBankAccount.bankAccount = bankAccount
    //     }
    //     else
    //     {
    //         println bankAccount.errors
    //     }
    //
    //     if (opportunity.validate())
    //     {
    //         opportunity.save flush: true
    //         OpportunityBankAccount.opportunity = opportunity
    //     }
    //     else
    //     {
    //         println opportunity.errors
    //     }
    //     if (OpportunityBankAccount.validate())
    //     {
    //         OpportunityBankAccount.save flush: true
    //     }
    //     else
    //     {
    //         println OpportunityBankAccount.errors
    //     }
    //     OpportunityContact loanOpportunityContact = new OpportunityContact()
    //     loanOpportunityContact.opportunity = opportunity
    //     loanOpportunityContact.contact = contact
    //     loanOpportunityContact.type = OpportunityContactType.findByName("借款人")
    //
    //     if (loanOpportunityContact.validate())
    //     {
    //         loanOpportunityContact.save flush: true
    //     }
    //     else
    //     {
    //         println loanOpportunityContact.errors
    //     }
    //
    //     println "initOpportunityFlow:" + opportunity?.id
    //     appOpportunityService.initOpportunity(opportunity)
    //     println "initFlow end"
    //
    //     render status: 200
    // }

    //信用贷借款接口
    def appCreateOpportunity1()
    {
        def json = request.JSON
        println "************************* appCreateOpportunity1 ***************************"
        println json
        def opportunity = new Opportunity()

        def loanAmount = json['loanAmount']
        //金额loanAmount
        def loanDuration = json['loanDuration']
        //期限loanDuration
        def loanUsage = json['loanUsage']
        //用途loanUsage
        def principalPaymentMethod = json['principalPaymentMethod']
        //还款方式principalPaymentMethod
        def actualLoanAmount = json['actualLoanAmount']
        //实际贷款额度
        def bankId = json['bankId']
        //银行卡id
        def sessionId = json["sessionId"]

        Contact contact = Contact.findByAppSessionId(sessionId)
        if (!sessionId)
        {
            def errors = [errorCode: 4300, errorMessage: "请登录"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        else if (!contact)
        {
            def errors = [errorCode: 4400, errorMessage: "您的账号已在别处登录！如非本人操作，请及时修改密码"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (!loanAmount || !(loanAmount?.matches(/^\d+(\.\d+)*$/)) || Double.parseDouble(loanAmount) <= 0)
        {
            def errors = [errorCode: 4201, errorMessage: "请输入正确的贷款金额"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (Double.parseDouble(loanAmount) > Double.parseDouble(actualLoanAmount))
        {
            def errors = [errorCode: 4201, errorMessage: "贷款金额超过了实际受信额度"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (!loanUsage)
        {
            def errors = [errorCode: 4201, errorMessage: "请输入借款用途"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (!loanDuration || !(loanDuration.matches(/^[0-9]\d*$/)) || Integer.parseInt(loanDuration) <= 0)
        {
            def errors = [errorCode: 4203, errorMessage: "请输入正确的贷款期限"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (!principalPaymentMethod)
        {
            def errors = [errorCode: 4203, errorMessage: "请输入还款方式"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (!bankId)
        {
            def errors = [errorCode: 4201, errorMessage: "请选择收款账户"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        opportunity.loanAmount = loanAmount.toDouble()
        opportunity.requestedAmount = loanAmount.toDouble()
        opportunity.loanDuration = loanDuration.toInteger()
        opportunity.loanUsage = loanUsage
        opportunity.principalPaymentMethod = PrincipalPaymentMethod.findByName(principalPaymentMethod)

        contact.level = ContactLevel.find("from ContactLevel where name = 'B'")
        // contact.type = "Client"

        if (contact.validate())
        {
            contact.save flush: true
        }
        else
        {
            println contact.errors
        }

        opportunity.user = contact?.user
        opportunity.account = contact?.user?.account
        opportunity.contact = contact
        opportunity.lender = contact

        opportunity.fullName = contact?.fullName
        opportunity.cellphone = contact?.cellphone
        opportunity.idNumber = contact?.idNumber

        def stage = OpportunityStage.findByCode("04")
        opportunity.stage = stage
        opportunity.type = OpportunityType.findByCode("01")

        Integer protectDays = 10
        Date protectionStartTime = new java.util.Date()
        opportunity.protectionStartTime = protectionStartTime
        opportunity.protectionEndTime = protectionStartTime + protectDays

        // 银行卡
        def OpportunityBankAccount = new OpportunityBankAccount()
        OpportunityBankAccount.type = OpportunityBankAccountType.findByName("收款账号")
        def bankAccount = BankAccount.findById(bankId)
        println "bankAccount:  " + bankAccount
        OpportunityBankAccount.bankAccount = bankAccount

        if (opportunity.validate())
        {
            opportunity.save flush: true
            OpportunityBankAccount.opportunity = opportunity
        }
        else
        {
            println opportunity.errors
        }
        println "opportunity:  " + opportunity
        if (OpportunityBankAccount.validate())
        {
            OpportunityBankAccount.save flush: true
        }
        else
        {
            println OpportunityBankAccount.errors
        }

        println "OpportunityBankAccount:  " + OpportunityBankAccount
        OpportunityContact loanOpportunityContact = new OpportunityContact()
        loanOpportunityContact.opportunity = opportunity
        loanOpportunityContact.contact = contact
        loanOpportunityContact.type = OpportunityContactType.findByName("借款人")

        if (loanOpportunityContact.validate())
        {
            loanOpportunityContact.save flush: true
        }
        else
        {
            println loanOpportunityContact.errors
        }
        println "OpportunityContact:  " + loanOpportunityContact

        //订单初始化
        opportunityService.initOpportunity(opportunity)
        //        render opportunity as JSON
        render JsonOutput.toJson([status: 200]), status: 200

    }

    //信用贷款 获取贷款额度
    @Secured(['permitAll'])
    def appCreditLine()
    {
        def json = request.JSON
        println "************************* appCreditLine ***************************"
        println json
        def sessionId = json["sessionId"]
        Contact contact = Contact.findByAppSessionId(sessionId)
        if (!sessionId)
        {
            def errors = [errorCode: 4300, errorMessage: "请登录"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        else if (!contact)
        {
            def errors = [errorCode: 4400, errorMessage: "您的账号已在别处登录！如非本人操作，请及时修改密码"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        // def amountSql = "select loan_amount from Opportunity where contact_id=${contact?.id}"
        def opportunityType = OpportunityType.findByCode('01')
        def amountSql = "select loanAmount from Opportunity where contact.id=${contact?.id} and type.id=${opportunityType?.id}"
        def amountList = Opportunity.executeQuery(amountSql)
        println "amountList： " + amountList
        Double maxLoanAmount = 50000
        Double actualLoanAmount = maxLoanAmount
        if (amountList)
        {
            for (
                def i = 0;
                    i < amountList.size();
                    i++)
            {
                actualLoanAmount = actualLoanAmount - amountList[i].toDouble()
            }

            actualLoanAmount = actualLoanAmount > 0 ? actualLoanAmount : 0

        }
        def amountMap = [:]
        amountMap['maxLoanAmount'] = maxLoanAmount
        amountMap['actualLoanAmount'] = actualLoanAmount
        println "amountMap:" + amountMap
        render amountMap as JSON
        return
    }

    // 信用贷款  获取银行账户
    @Secured(['permitAll'])
    def appBankAccount()
    {
        def json = request.JSON
        println "************************* appBankAccount ***************************"
        println json
        def sessionId = json["sessionId"]
        Contact contact = Contact.findByAppSessionId(sessionId)
        if (!sessionId)
        {
            def errors = [errorCode: 4300, errorMessage: "请登录"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        else if (!contact)
        {
            def errors = [errorCode: 4400, errorMessage: "您的账号已在别处登录！如非本人操作，请及时修改密码"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        def bankAccountList = ContactBankAccount.findAll("from ContactBankAccount where contact_id=${contact?.id} and bankAccount.active = true order by modifiedDate desc")
        println "bankAccountList:  " + bankAccountList
        def bankList = []
        if (bankAccountList)
        {
            bankAccountList?.each {
                def bankAccountMap = [:]
                bankAccountMap['bankId'] = it?.bankAccount?.id
                bankAccountMap['numberOfAccount'] = it?.bankAccount?.numberOfAccount
                bankAccountMap['bankName'] = it?.bankAccount?.bank?.name
                bankList.add(bankAccountMap)
            }
            //            for(def i=0;i<bankAccountList.size();i++){
            //                def bankAccountMap=[:]
            //                bankAccountMap.put("bankId":bankAccountList[i]?.bankAccount?.id)
            //                bankAccountMap.put("numberOfAccount":bankAccountList[i]?.bankAccount?.numberOfAccount)
            //                bankAccountMap.put("bankName":bankAccountList[i]?.bankAccount?.bankName)
            //                bankList.add(bankAccountMap)
            //            }
        }
        render bankList as JSON
        return

    }

    //云丛网贷添加银行卡接口
    @Secured(['permitAll'])
    def appCreateBankCard()
    {
        def json = request.JSON
        println "************************* appCreateBankCard ***************************"
        println json
        def sessionId = json["sessionId"]
        def numberOfAccount = json['numberOfAccount']
        //银行卡号
        def bankName = json['bankName']
        //银行卡类型
        def cellphone = json['cellphone']
        //手机号

        Contact contact = Contact.findByAppSessionId(sessionId)
        def contactBankAccount = new ContactBankAccount()
        if (!sessionId)
        {
            def errors = [errorCode: 4300, errorMessage: "请登录"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        else if (!contact)
        {
            def errors = [errorCode: 4400, errorMessage: "您的账号已在别处登录！如非本人操作，请及时修改密码"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (!cellphone || !(cellphone.matches(/^1\d{10}$/)))
        {
            def errors = [errorCode: 2000, errorMessage: "请填写正确的手机号"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (!numberOfAccount)
        {
            def errors = [errorCode: 2000, errorMessage: "请填写银行卡号"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (!bankName)
        {
            def errors = [errorCode: 2000, errorMessage: "请填写银行卡类型"]
            render JsonOutput.toJson(errors), status: 400
            return
        }

        def bankAccount = new BankAccount()
        bankAccount.cellphone = cellphone
        bankAccount.numberOfAccount = numberOfAccount
        bankAccount.bank = Bank.findByName(bankName)
        bankAccount.name = contact?.fullName
        bankAccount.certificateType = ContactIdentityType.findByName("个人居民身份证")
        bankAccount.numberOfCertificate = contact?.idNumber
        bankAccount.paymentChannel = PaymentChannel.findByName("广银联")
        bankAccount.active = false

        if (bankAccount.validate())
        {
            bankAccount.save flush: true
        }
        else
        {
            println bankAccount.errors
        }
        println "bankAccount: " + bankAccount
        contactBankAccount.contact = contact
        contactBankAccount.bankAccount = bankAccount
        if (contactBankAccount.validate())
        {
            contactBankAccount.save flush: true
        }
        else
        {
            println contactBankAccount.errors
        }
        render bankAccount as JSON
    }

    @Secured(['permitAll'])
    def appNameIsAuthenticated()
    {
        def json = request.JSON
        println "************************* appNameIsAuthenticated ***************************"
        println json
        def sessionId = json["sessionId"]
        def message = [:]
        Contact contact = Contact.findByAppSessionId(sessionId)
        if (!sessionId)
        {
            def errors = [errorCode: 4300, errorMessage: "请登录"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        else if (!contact)
        {
            def errors = [errorCode: 4400, errorMessage: "您的账号已在别处登录！如非本人操作，请及时修改密码"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (contact?.fullName && contact?.idNumber)
        {
            message['isAuthenticated'] = true
        }
        else
        {
            message['isAuthenticated'] = false
        }

        render JsonOutput.toJson(message)

    }

    //云丛网贷实名认证接口
    @Secured(['permitAll'])
    def appRealnameAuthentication()
    {
        def json = request.JSON
        println "************************* appRealnameAuthentication ***************************"
        println json
        def sessionId = json["sessionId"]
        def fullName = json['fullName']
        //姓名
        def idNumber = json['idNumber']
        //身份证号

        Contact contact = Contact.findByAppSessionId(sessionId)
        if (!sessionId)
        {
            def errors = [errorCode: 4300, errorMessage: "请登录"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        else if (!contact)
        {
            def errors = [errorCode: 4400, errorMessage: "您的账号已在别处登录！如非本人操作，请及时修改密码"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (!fullName || !(fullName.matches(/^[\u2190-\u9fff]{1,10}$|^[\dA-Za-z]{1,20}$/)))
        {
            def errors = [errorCode: 4209, errorMessage: "请输入正确的姓名"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (!idNumber || !contactService.verifyIdNumber(idNumber))
        {
            println "idNumber format error"
            def errors = [errorCode: 4006, errorMessage: "请输入正确的身份证号"]
            render JsonOutput.toJson(errors), status: 400
            return

        }
        contact.fullName = fullName
        contact.idNumber = idNumber
        if (contact.validate())
        {
            contact.save()
            render JsonOutput.toJson([status: 200]), status: 200
        }
        else
        {
            def errors = [errorCode: 9000, errorMessage: contact.errors]
            render JsonOutput.toJson(errors), status: 400
        }

    }

    //信用贷获取还款日
    @Secured(['permitAll'])
    def appRepaymentDate()
    {
        def json = request.JSON
        println "************************* appRepaymentDate ***************************"
        println json
        def sessionId = json["sessionId"]
        Date firstLoanDate
        Integer day
        def repaymentDay = [:]
        Contact contact = Contact.findByAppSessionId(sessionId)
        if (!sessionId)
        {
            def errors = [errorCode: 4300, errorMessage: "请登录"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        else if (!contact)
        {
            def errors = [errorCode: 4400, errorMessage: "您的账号已在别处登录！如非本人操作，请及时修改密码"]
            render JsonOutput.toJson(errors), status: 400
            return
        }

        def opportunityType = OpportunityType.findByCode('01')
        def opportunity = Opportunity.find("from Opportunity where contact.id = ${contact.id} and type.id = ${opportunityType.id} order by createdDate asc")
        if (opportunity)
        {
            firstLoanDate = opportunity?.createdDate
        }
        else
        {
            firstLoanDate = new Date()
        }
        println "firstLoanDate:" + firstLoanDate
        day = firstLoanDate.getDate()
        println "day:" + day

        if (day == 29)
        {
            day = 25
        }
        if (day == 30)
        {
            day = 26
        }
        if (day == 31)
        {
            day = 27
        }
        println "DAY:" + day
        repaymentDay['day'] = day

        render repaymentDay as JSON
    }

    @Secured(['permitAll'])
    @Transactional
    def appQuery()
    {
        def offset = params['offset']?.toInteger()
        def sessionId = params["sessionId"]
    }

    @Secured(['permitAll'])
    @Transactional
    def appProjectTime()
    {
        def json = request.JSON
        println "************************* appProjectTime ***************************"
        println json

        def sessionId = json["sessionId"]
        String requestedAmount = json["requestedAmount"].toString()
        String loanDuration = json["loanDuration"]
        String fullName = json["fullName"]
        //旧版
        String idNumber = json["idNumber"]

        Contact contact = Contact.findByAppSessionId(sessionId)
        if (!sessionId)
        {
            def errors = [errorCode: 4300, errorMessage: "请登录"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        else if (!contact)
        {
            def errors = [errorCode: 4400, errorMessage: "您的账号已在别处登录！如非本人操作，请及时修改密码"]
            render JsonOutput.toJson(errors), status: 400
            return
        }

        if (idNumber)
        {
            //旧版
            Boolean inProtectTime = opportunityService.verifyProtectionTime(idNumber)
            if (inProtectTime)
            {
                def errors = [errorCode: 4555, errorMessage: "借款人处于保护期，不允许报单"]
                render JsonOutput.toJson(errors), status: 400
                return
            }
            render JsonOutput.toJson([status: 200]), status: 200
        }
        else
        {
            //新版
            if (!fullName || !(fullName.matches(/^[\u2190-\u9fff]{1,10}$|^[\dA-Za-z]{1,20}$/)))
            {
                def errors = [errorCode: 4209, errorMessage: "请输入正确的借款人姓名"]
                render JsonOutput.toJson(errors), status: 400
                return
            }
            if (!requestedAmount || !(requestedAmount.matches(/^\d+(\.\d+)*$/)) || Double.parseDouble(requestedAmount) <= 0)
            {
                def errors = [errorCode: 4201, errorMessage: "请输入正确的贷款金额"]
                render JsonOutput.toJson(errors), status: 400
                return
            }
            if (!loanDuration || !(loanDuration.matches(/^[0-9]\d*$/)) || Integer.parseInt(loanDuration) <= 0)
            {
                def errors = [errorCode: 4203, errorMessage: "请输入正确的贷款期限"]
                render JsonOutput.toJson(errors), status: 400
                return
            }
            if (Opportunity.findByFullNameAndRequestedAmountAndLoanDurationAndStatusAndProtectionEndTimeGreaterThan(fullName, Double.parseDouble(requestedAmount), Integer.parseInt(loanDuration), 'Pending', new Date()))
            {
                def errors = [errorCode: 4555, errorMessage: "借款人处于保护期，不允许报单"]
                render JsonOutput.toJson(errors), status: 400
                return
            }

            render JsonOutput.toJson([status: 200]), status: 200
        }

    }

    @Secured(['permitAll'])
    /*@Transactional*/
    def appCreateOpportunity()
    {
        def json = request.JSON
        println "************************* appCreateOpportunity ***************************"
        println json

        def sessionId = json["sessionId"]
        Contact contact = Contact.findByAppSessionId(sessionId)
        if (!sessionId)
        {
            def errors = [errorCode: 4300, errorMessage: "请登录"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        else if (!contact)
        {
            def errors = [errorCode: 4400, errorMessage: "您的账号已在别处登录！如非本人操作，请及时修改密码"]
            render JsonOutput.toJson(errors), status: 400
            return
        }

        Opportunity opportunity = new Opportunity()
        opportunity.status = "Pending"
        opportunity.stage = OpportunityStage.findByCode("02")
        opportunity.account = contact?.user?.account
        opportunity.user = contact?.user
        opportunity.loanApplicationProcessType = LoanApplicationProcessType.findByName("先评房再报单")

        if (opportunity.validate())
        {
            opportunity.save flush: true
        }
        else
        {
            println opportunity.errors
        }

        render opportunity as JSON
        return
    }

    @Secured(['permitAll'])
    /*@Transactional*/
    def appSubmit()
    {
        def json = request.JSON
        println "************************* appSubmit ***************************"
        println json

        String sessionId = json["sessionId"]
        Contact contact = Contact.findByAppSessionId(sessionId)
        if (!sessionId)
        {
            def errors = [errorCode: 4300, errorMessage: "请登录"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        else if (!contact)
        {
            def errors = [errorCode: 4400, errorMessage: "您的账号已在别处登录！如非本人操作，请及时修改密码"]
            render JsonOutput.toJson(errors), status: 400
            return
        }

        String serialNumber = json["opportunity"]["serialNumber"]
        String requestedAmount = json["opportunity"]["requestedAmount"].toString()
        String loanDuration = json["opportunity"]["loanDuration"]
        String mortgageType = json["opportunity"]["mortgageType"]
        String firstMortgageAmount = json["opportunity"]["firstMortgageAmount"]?.toString()
        String secondMortgageAmount = json["opportunity"]["secondMortgageAmount"]?.toString()
        String typeOfFirstMortgage = json["opportunity"]["typeOfFirstMortgage"]
        String fullName = json["opportunity"]["fullName"]
        String maritalStatus = json["opportunity"]["maritalStatus"]
        String mortgageStatus = json["opportunity"]["mortgageStatus"]
        String cellphone = json["opportunity"]["cellphone"]
        //兼容
        def contacts = json["opportunity"]["contacts"]

        Integer protectDays = 10
        if (cellphone)
        {
            protectDays += 5
            if (!(cellphone.matches(/^1\d{10}$/)))
            {
                def errors = [errorCode: 4216, errorMessage: "借款人手机号格式不正确，请重新输入"]
                render JsonOutput.toJson(errors), status: 400
                return
            }
        }
        Opportunity opportunity = Opportunity.findBySerialNumber(serialNumber)
        if (!opportunity || !serialNumber)
        {
            def errors = [errorCode: 4200, errorMessage: "请选择房源"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (!requestedAmount || !(requestedAmount.matches(/^\d+(\.\d+)*$/)) || Double.parseDouble(requestedAmount) <= 0)
        {
            def errors = [errorCode: 4201, errorMessage: "请输入正确的贷款金额"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (!loanDuration || !(loanDuration.matches(/^[0-9]\d*$/)) || Integer.parseInt(loanDuration) <= 0)
        {
            def errors = [errorCode: 4203, errorMessage: "请输入正确的贷款期限"]
            render JsonOutput.toJson(errors), status: 400
            return
        }

        if (!mortgageType || !(mortgageType in ["一抵", "二抵", "一抵转单", "二抵转单"]))
        {
            def errors = [errorCode: 4205, errorMessage: "请选择抵押类型"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (mortgageType == "一抵")
        {
            firstMortgageAmount = "0"
            secondMortgageAmount = "0"
        }
        if ((mortgageType in ["二抵", "一抵转单"]))
        {
            if (!firstMortgageAmount || !(firstMortgageAmount.matches(/^\d+(\.\d+)*$/)) || Double.parseDouble(firstMortgageAmount) <= 0)
            {
                def errors = [errorCode: 4206, errorMessage: "请输入正确的一抵金额"]
                render JsonOutput.toJson(errors), status: 400
                return
            }
            if (!typeOfFirstMortgage || !(typeOfFirstMortgage in ["银行类", "非银行类"]))
            {
                def errors = [errorCode: 4207, errorMessage: "请选择一抵类型"]
                render JsonOutput.toJson(errors), status: 400
                return
            }
            secondMortgageAmount = "0"
        }
        if (mortgageType == "二抵转单")
        {
            if (!firstMortgageAmount || !(firstMortgageAmount.matches(/^\d+(\.\d+)*$/)) || Double.parseDouble(firstMortgageAmount) <= 0)
            {
                def errors = [errorCode: 4206, errorMessage: "请输入正确的一抵金额"]
                render JsonOutput.toJson(errors), status: 400
                return
            }
            if (!typeOfFirstMortgage || !(typeOfFirstMortgage in ["银行类", "非银行类"]))
            {
                def errors = [errorCode: 4207, errorMessage: "请选择一抵类型"]
                render JsonOutput.toJson(errors), status: 400
                return
            }
            if (!secondMortgageAmount || !(secondMortgageAmount.matches(/^\d+(\.\d+)*$/)) || Double.parseDouble(secondMortgageAmount) <= 0)
            {
                def errors = [errorCode: 4208, errorMessage: "请输入正确的二抵金额"]
                render JsonOutput.toJson(errors), status: 400
                return
            }
        }
        if (!fullName || !(fullName.matches(/^[\u2190-\u9fff]{1,10}$|^[\dA-Za-z]{1,20}$/)))
        {
            def errors = [errorCode: 4209, errorMessage: "请输入正确的借款人姓名"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (!maritalStatus || !(maritalStatus in ["未婚", "已婚", "再婚", "离异", "丧偶"]))
        {
            println "ddd"
            def errors = [errorCode: 4212, errorMessage: "请选择借款人婚姻状况"]
            render JsonOutput.toJson(errors), status: 400
            return
        }

        boolean contacts_flag = true
        println "debug1:" + contacts_flag
        if (contacts)
        {
            println "debug2"
            for (
                it in
                    contacts)
            {
                if (it['idNumber'])
                {
                    if (it["type"] && (it["type"] in ["借款人配偶", "抵押人", "抵押人配偶"]))
                    {
                        if (!it["idNumber"] || !contactService.verifyIdNumber(it["idNumber"]))
                        {
                            def errors = [errorCode: 4215, errorMessage: "请输入正确的${it["type"]}身份证号"]
                            render JsonOutput.toJson(errors), status: 400
                            contacts_flag = false
                            return
                            break
                        }
                        else if (!it["fullName"] || !(it["fullName"].matches(/^[\u2190-\u9fff]{1,10}$|^[\dA-Za-z]{1,20}$/)))
                        {
                            def errors = [errorCode: 4219, errorMessage: "请输入正确的${it["type"]}姓名"]
                            render JsonOutput.toJson(errors), status: 400
                            contacts_flag = false
                            return
                            break
                        }
                        else if (it["cellphone"])
                        {
                            if (!(it["cellphone"].matches(/^1\d{10}$/)))
                            {
                                def errors = [errorCode: 4216, errorMessage: "${it["type"]}手机号格式不正确，请重新输入"]
                                render JsonOutput.toJson(errors), status: 400
                                contacts_flag = false
                                return
                                break
                            }
                            else
                            {
                                protectDays += 5
                            }
                        }
                    }
                    else
                    {
                        def errors = [errorCode: 4218, errorMessage: "请输入正确的联系人类型"]
                        render JsonOutput.toJson(errors), status: 400
                        contacts_flag = false
                        return
                        break
                    }
                }

            }
        }
        println "bug:" + contacts_flag
        if (contacts_flag)
        {
            println "debug3"
            //兼容
            if (contacts)
            {
                for (
                    it in
                        contacts)
                {
                    if (it['idNumber'])
                    {
                        def contactFullName = it["fullName"]
                        def contactIdNumber = it["idNumber"]
                        def contactCellphone = it["cellphone"]
                        def contactMaritalStatus = "已婚"
                        if (it["mortgagorMaritalStatus"])
                        {
                            contactMaritalStatus = it["mortgagorMaritalStatus"]
                        }
                        def type = it["type"]
                        if (contactIdNumber)
                        {
                            opportunityService.addContacts(contactFullName, contactIdNumber, contactCellphone, contactMaritalStatus, type, opportunity)
                        }
                        continue
                    }

                }
            }

            if (Opportunity.findByFullNameAndRequestedAmountAndLoanDurationAndStatusAndProtectionEndTimeGreaterThan(fullName, Double.parseDouble(requestedAmount), Integer.parseInt(loanDuration), 'Pending', new Date()))
            {
                println "debug5"
                def errors = [errorCode: 4220, errorMessage: "借款人处于保护期，不可以报单"]
                render JsonOutput.toJson(errors), status: 400
            }
            else
            {
                println "debug6"
                Contact loanContact = new Contact()
                loanContact.fullName = fullName
                loanContact.maritalStatus = maritalStatus
                loanContact.cellphone = cellphone
                loanContact.user = contact?.user
                loanContact.account = contact?.account
                loanContact.level = ContactLevel.findByName("待评级")
                loanContact.type = "Client"
                //旧版
                if (json["opportunity"]["idNumber"])
                {
                    loanContact.idNumber = json["opportunity"]["idNumber"]
                }
                loanContact.save flush: true

                Contact mortgageContact = null
                if (mortgageStatus)
                {
                    mortgageContact = new Contact()
                    mortgageContact.fullName = "抵押人姓名"
                    mortgageContact.maritalStatus = mortgageStatus
                    mortgageContact.user = contact?.user
                    mortgageContact.account = contact?.account
                    mortgageContact.save flush: true
                }

                opportunity.requestedAmount = Double.parseDouble(requestedAmount) * 10000
                opportunity.loanDuration = Integer.parseInt(loanDuration)
                //实际贷款期限取默认值为拟贷款期限
                opportunity.actualLoanDuration = Integer.parseInt(loanDuration)

                opportunity.mortgageType = MortgageType.findByName(mortgageType)
                opportunity.firstMortgageAmount = Double.parseDouble(firstMortgageAmount)
                opportunity.typeOfFirstMortgage = TypeOfFirstMortgage.findByName(typeOfFirstMortgage)
                opportunity.secondMortgageAmount = Double.parseDouble(secondMortgageAmount)

                def houses = House.findAll("from House where opportunity.id = ${opportunity?.id} order by id asc")
                println "houses" + houses.size()
                if (houses?.size() == 1)
                {
                    def house = House.findByOpportunity(opportunity)
                    house.firstMortgageAmount = Double.parseDouble(firstMortgageAmount)
                    house.secondMortgageAmount = Double.parseDouble(secondMortgageAmount)
                    house.mortgageType = MortgageType.findByName(mortgageType)
                    house.typeOfFirstMortgage = TypeOfFirstMortgage.findByName(typeOfFirstMortgage)
                    house.save flush: true
                }

                opportunity.fullName = fullName
                //旧版
                if (json["opportunity"]["idNumber"])
                {
                    opportunity.idNumber = json["opportunity"]["idNumber"]
                }
                opportunity.contact = contact
                opportunity.lender = loanContact
                opportunity.maritalStatus = maritalStatus
                opportunity.stage = OpportunityStage.findByCode("70")
                Date protectionStartTime = new java.util.Date()
                opportunity.protectionStartTime = protectionStartTime
                opportunity.protectionEndTime = protectionStartTime + protectDays
                opportunity.territory = Territory.findByName("测试区-光大银行")
                //                opportunity.createdDate = new Date()
                //                opportunity.modifiedDate = new Date()
                if (opportunity.validate())
                {
                    opportunity.save flush: true
                }
                else
                {
                    opportunity.errors.each {
                        println it
                    }
                }

                OpportunityContact loanOpportunityContact = new OpportunityContact()
                loanOpportunityContact.opportunity = opportunity
                loanOpportunityContact.contact = loanContact
                loanOpportunityContact.type = OpportunityContactType.findByName("借款人")
                loanOpportunityContact.save flush: true

                if (mortgageContact)
                {
                    OpportunityContact mortgageOpportunityContact = new OpportunityContact()
                    mortgageOpportunityContact.opportunity = opportunity
                    mortgageOpportunityContact.contact = mortgageContact
                    mortgageOpportunityContact.type = OpportunityContactType.findByName("抵押人")
                    mortgageOpportunityContact.save flush: true
                }

                //订单初始化
                //                opportunityService.initOpportunity(opportunity)
                appOpportunityService.initOpportunity(opportunity)

                def currentWorkflowInstance = WorkflowInstance.findByOpportunity(opportunity)
                if (currentWorkflowInstance)
                {
                    def currentInstanceStage
                    if (opportunity?.stage?.code == "70")
                    {
                        currentInstanceStage = WorkflowInstanceStage.findByInstanceAndName(currentWorkflowInstance, "基础材料已提供")
                    }

                    currentWorkflowInstance.stage = currentInstanceStage
                    currentWorkflowInstance.save flush: true
                }

                if (houses?.size() == 0)
                {
                    println "********** 极速询值 appQuery3 *************"
                    def city = "北京市"

                    println "######新建房产信息###########"
                    // def house = house.findByOpportunity(opportunity)
                    def house = new House()
                    house.opportunity = opportunity
                    house.requestStartTime = new Date()
                    house.city = City.findByName(city)
                    house.district = "未知"
                    house.projectName = "未知"
                    house.building = 0
                    house.orientation = "未知"
                    house.unit = "未知"
                    house.atticArea = 0
                    house.floor = 0
                    house.roomNumber = "未知"
                    house.totalFloor = 0
                    house.area = 0
                    house.address = "未知"
                    house.houseType = "未知"
                    house.assetType = "未知"
                    house.specialFactors = "未知"
                    house.appliedTotalPrice = 0
                    house.opportunity = opportunity

                    // def result = propertyValuationProviderService.createhouse(house)
                    def result = [externalId: '']
                    println "result:" + result
                    if (result)
                    {
                        def externalId = result['externalId']?.toString()
                        // house.opportunity = opportunity
                        house.unitPrice = 0
                        house.totalPrice = 0
                        house.externalId = externalId
                        house.status = "Pending"

                        if (house.validate())
                        {
                            house.save flush: true
                        }
                        else
                        {
                            println house.errors
                        }

                        def result1 = [:]
                        result1['reasonOfPriceAdjustment'] = "unknown"
                        result1['appliedTotalPrice'] = 0

                        def ats = []
                        def attachmentsList = Attachments.findAllByOpportunityAndType(opportunity, AttachmentType.findByName('房产证'))
                        attachmentsList?.each {
                            def simple = [:]
                            simple['fileName'] = it?.fileUrl
                            simple['attachmentType'] = "房产证"
                            ats.add(simple)
                        }
                        result1['attachments'] = ats
                        result1['externalId'] = house.externalId

                        def resultJson = ""
                        println "result1:" + result1
                        String param = result1 as JSON
                        println param
                        // resultJson = propertyValuationProviderService.suggestSubmmit1(param)

                        // if (!resultJson) {
                        //     def errors = [errorCode: 4796, errorMessage: "调用评房反馈服务上传图片失败，请稍后重试"]
                        //     render JsonOutput.toJson(errors), status: 400
                        // }
                    }
                    else
                    {
                        def errors = [errorCode: 4604, errorMessage: "网络不稳定，请稍后重试"]
                        render JsonOutput.toJson(errors), status: 400
                    }
                    render opportunity as JSON
                    return
                }
                else
                {
                    //A类重评
                    def house = House.findByOpportunity(opportunity)
                    // def pvJson = propertyValuationProviderService.queryByExternalId(house?.externalId)
                    // def valuationReliability = pvJson['valuationReliability']
                    // if (valuationReliability)
                    // {
                    //     if (valuationReliability == 'A')
                    //     {
                    //         def result = propertyValuationProviderService.createhouse1(house)
                    //         if (result)
                    //         {
                    //             house.externalId = result['externalId']?.toString()
                    //             house.status = result['status']?.toString()
                    //             house.save()
                    //             def ats = []
                    //             def result1 = [:]
                    //             def attachmentsList = Attachments.findAllByOpportunityAndType(opportunity, AttachmentType.findByName('房产证'))
                    //             attachmentsList?.each {
                    //                 def simple = [:]
                    //                 simple['fileName'] = it?.fileUrl
                    //                 simple['attachmentType'] = "房产证"
                    //                 ats.add(simple)
                    //             }
                    //             result1['attachments'] = ats
                    //             result1['externalId'] = house.externalId
                    //
                    //             def resultJson = ""
                    //             println "result1:" + result1
                    //             String param = result1 as JSON
                    //             println param
                    //             resultJson = propertyValuationProviderService.suggestSubmmit1(param)
                    //
                    //             if (!resultJson)
                    //             {
                    //                 def errors = [errorCode: 4796, errorMessage: "调用评房反馈服务上传图片失败，请稍后重试"]
                    //                 render JsonOutput.toJson(errors), status: 400
                    //             }
                    //         }
                    //         else
                    //         {
                    //             def errors = [errorCode: 4604, errorMessage: "网络不稳定，请稍后重试"]
                    //             render JsonOutput.toJson(errors), status: 400
                    //         }
                    //     }
                    // }
                    // else
                    // {
                    //   def errors = [errorCode: 4604, errorMessage: "网络不稳定，请稍后重试"]
                    //   render JsonOutput.toJson(errors), status: 400
                    // }
                    def result1 = [:]
                    // result1['reasonOfPriceAdjustment'] = "unknown"
                    // result1['appliedTotalPrice'] = 0

                    def ats = []
                    def attachmentsList = Attachments.findAllByOpportunityAndType(opportunity, AttachmentType.findByName('房产证'))
                    attachmentsList?.each {
                        def simple = [:]
                        simple['fileName'] = it?.fileUrl
                        simple['attachmentType'] = "产证照片"
                        ats.add(simple)
                    }
                    result1['attachments'] = ats
                    result1['externalId'] = house.externalId

                    def resultJson = ""
                    println "result1:" + result1
                    String param = result1 as JSON
                    println param
                    // resultJson = propertyValuationProviderService.suggestSubmmit2(param)

                    // if (!resultJson) {
                    //     def errors = [errorCode: 4796, errorMessage: "调用评房反馈服务上传图片失败，请稍后重试"]
                    //     render JsonOutput.toJson(errors), status: 400
                    // }

                    render opportunity as JSON
                    return
                }
            }

        }
        else
        {
            println "debug4"
            def errors = [errorCode: 4218, errorMessage: "请输入正确的信息"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
    }

    //快手贷
    //订单列表
    @Secured(['permitAll'])
    @Transactional
    def appQueryByStageAndStatus()
    {
        def json = request.JSON
        println "************************* appQueryByStageAndStatus ***************************"
        println json

        def max = 10
        def stages = json["stages"]
        def offset = json['offset']?.toInteger()
        String sessionId = json["sessionId"]
        def status = json["status"]

        def queryType = json["queryType"]
        String paramValue = json["paramValue"]

        def contact = Contact.findByAppSessionId(sessionId)
        if (!sessionId)
        {
            def errors = [errorCode: 4300, errorMessage: "请登录"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        else if (!contact)
        {
            def errors = [errorCode: 4400, errorMessage: "您的账号已在别处登录！如非本人操作，请及时修改密码"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (!stages || stages?.size() == 0)
        {
            def errors = [errorCode: 4260, errorMessage: "请输入要查询的订单状态"]
            render JsonOutput.toJson(errors), status: 400
            return
        }

        def opportunityIdList = []

        if (queryType == "search")
        {
            if (!paramValue)
            {
                def errors = [errorCode: 4274, errorMessage: "请输入查询参数"]
                render JsonOutput.toJson(errors), status: 400
                return
            }
            def list1 = []
            def list2 = []

            paramValue = "%" + paramValue + "%"
            list1 = Opportunity.executeQuery("select o.id from Opportunity as o, House as c where o.id = c.opportunity.id and o.contact.id = :contact and o.stage.name in :stage and (o.fullName like :fullName or o.serialNumber like :serialNumber or c.address like :address or c.projectName like :projectName)", [contact: contact?.id, stage: stages, fullName: paramValue, serialNumber: paramValue, address: paramValue, projectName: paramValue])
            list2 = Opportunity.executeQuery("select id from Opportunity as o  where o.contact.id = :contact and o.stage.name in :stage and (o.fullName like :fullName or o.serialNumber like :serialNumber)", [contact: contact?.id, stage: stages, fullName: paramValue, serialNumber: paramValue])

            println list1.size()
            println list2.size()
            println "list1:" + list1

            if (list1.size() > 0)
            {
                list1?.each {
                    opportunityIdList.add(it)
                    if (list2.contains(it))
                    {
                        list2 -= it
                    }
                }
            }

            if (list2?.size() > 0)
            {
                list2?.each {
                    opportunityIdList.add(it)
                }
            }
            println opportunityIdList

        }
        else
        {
            if (!status)
            {
                def errors = [errorCode: 4262, errorMessage: "请输入订单结果"]
                render JsonOutput.toJson(errors), status: 400
                return
            }

            def sql = "select id from Opportunity as o where  o.contact.id = :contact and o.stage.name in :stage and o.status in :status"
            def searchParam = [:]
            searchParam['contact'] = contact?.id
            searchParam['stage'] = stages
            searchParam['status'] = status

            sql += " order by createdDate desc "
            println "sql:" + sql
            if (offset != null)
            {
                searchParam['max'] = max
                searchParam['offset'] = offset * 10
                opportunityIdList = Opportunity.executeQuery(sql, searchParam)
            }
            else
            {
                opportunityIdList = Opportunity.executeQuery(sql, searchParam)
            }
        }

        //        def opportunityIdList = [103364]
        def opportunityList = []
        def db = new Sql(dataSource)
        opportunityIdList.each {
            def oppMap = [:]
            def opportunityBase = db.rows("SELECT  stage_id,lender_id, loan_amount, interest_payment_method_id, actual_amount_of_credit, cause_of_failure_id, status, serial_number, created_date,requested_amount,loan_duration,  mortgage_type_id,   full_name,  id_number,  marital_status, protection_start_time,  protection_end_time,  id ,valuation_type from opportunity where id = ?", [it])[0]
            oppMap.put("loanAmount", opportunityBase[2])
            oppMap.put("interestPaymentMethod", ["name": InterestPaymentMethod.findById(opportunityBase[3])?.name])
            oppMap.put("actualAmountOfCredit", opportunityBase[4])
            oppMap.put("causeOfFailure", ["name": CauseOfFailure.findById(opportunityBase[5])]?.name)
            oppMap.put("status", opportunityBase[6])
            oppMap.put("serialNumber", opportunityBase[7])
            oppMap.put("createdDate", opportunityBase[8])
            oppMap.put("requestedAmount", opportunityBase[9])
            oppMap.put("loanDuration", opportunityBase[10])
            oppMap.put("mortgageType", ["name": MortgageType.findById(opportunityBase[11])?.name])
            oppMap.put("fullName", opportunityBase[12])
            oppMap.put("idNumber", opportunityBase[13])
            oppMap.put("maritalStatus", opportunityBase[14])
            oppMap.put("protectionStartTime", opportunityBase[15])
            oppMap.put("protectionEndTime", opportunityBase[16])
            oppMap.put("id", opportunityBase[17])
            oppMap.put("valuationType", opportunityBase[18])

            def houses = db.rows("SELECT city_id,reason_of_price_adjustment,id,address,project_name,building,room_number,orientation,area,house_type,special_factors,status ,total_price  from House WHERE opportunity_id = ? ", [it])[0]
            def map1 = [:]
            def housesList = []
            def map = [:]
            if (houses)
            {
                def cityName = City.findById(houses[0])?.name
                map.put("name", cityName)
                map1.put("city", map)
                map1.put("reasonOfPriceAdjustment", houses[1])
                map1.put("id", houses[2])
                map1.put("address", houses[3])
                map1.put("projectName", houses[4])
                map1.put("building", houses[5])
                map1.put("roomNumber", houses[6])
                map1.put("orientation", houses[7])
                map1.put("area", houses[8])
                map1.put("houseType", houses[9])
                map1.put("specialFactors", houses[10])
                map1.put("status", houses[11])
                map1.put("totalPrice", houses[12])
            }

            housesList.add(map1)
            oppMap.put("houses", housesList)

            def opportunityContacts = db.rows("SELECT type_id,contact_id from opportunity_contact where opportunity_id = ? ", [it])
            def opportunityContactsList = []
            opportunityContacts.each {
                def contactType = db.rows("SELECT name from opportunity_contact_type where id = ? ", [it[0]])[0]
                def contacts = db.rows("SELECT full_name,id_number,marital_status FROM  contact WHERE id = ?", [it[1]])[0]
                map = [:]
                map1 = [:]
                def map2 = [:]
                map1.put("fullName", contacts[0])
                map1.put("idNumber", contacts[1])
                map1.put("maritalStatus", contacts[2])
                map.put("name", contactType[0])
                map2.put("contact", map1)
                map2.put("type", map)
                opportunityContactsList.add(map2)
            }
            oppMap.put("contacts", opportunityContactsList)

            def stageName = db.rows("SELECT name from opportunity_stage where id = ?", [opportunityBase[0]])[0]
            map1 = [:]

            map1.put("name", stageName[0])
            oppMap.put("stage", map1)

            def lenderId = db.rows("SELECT level_id from contact WHERE id = ? ", [opportunityBase[1]])[0]
            map = [:]
            map1 = [:]
            if (lenderId)
            {
                def level = db.rows("SELECT name,description FROM contact_level WHERE id = ? ", [lenderId[0]])[0]
                if (level)
                {
                    map.put("name", level[0])
                    map.put("description", level[1])
                }

            }

            map1.put("level", map)
            oppMap.put("lender", map1)
            //房产证
            def houseAttachment = AttachmentType.findByName("房产证")
            def attachments = db.rows("SELECT file_name,file_url FROM attachments WHERE opportunity_id = ? and type_id = ${houseAttachment?.id}", [it])
            def attachmentsList = []
            attachments.each {
                map = [:]
                map.put("fileName", it[0])
                map.put("fileUrl", it[1])
                map.put("type", ["name": "房产证"])
                attachmentsList.add(map)
            }
            oppMap.put("attachments", attachmentsList)

            def opportunityComments = db.rows("select u.full_name,c.modified_date,c.comment,c.is_read from opportunity_comments c inner join login_user u on c.user_id = u.id inner join opportunity o on c.opportunity_id = o.id where o.id = ? order by c.modified_date desc", [it])
            def comments = []
            def isRead = "1"
            opportunityComments.each {
                map = [:]
                map.put("fullName", it[0])
                map.put("createdDate", it[1].format("yyyy-MM-dd HH:mm:ss"))
                map.put("comment", it[2])
                if (it[3] == false)
                {
                    isRead = "0"
                }
                comments.add(map)
            }
            oppMap.put("isRead", isRead)
            oppMap.put("comments", comments)
            opportunityList.add(oppMap)
        }
        render opportunityList as JSON
        return
    }

    /** @Description 查询经纪人名下订单是否有新消息* @Params sessionId* @Return json* @Author Nagelan* @DateTime 2018/12/6 0006 16:58
     */
    @Secured(['permitAll'])
    def queryStatusForComments()
    {
        def db = new groovy.sql.Sql(dataSource)
        def json = request.JSON
        def sessionId = json.sessionId
        def contact = Contact.findByAppSessionId(sessionId)
        if (!sessionId)
        {
            def errors = [errorCode: 4300, errorMessage: "请登录"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        else if (!contact)
        {
            def errors = [errorCode: 4400, errorMessage: "您的账号已在别处登录！如非本人操作，请及时修改密码"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        def map = [:]
        def status = "1"
        def opportunityComments = db.rows("select c.id from opportunity_comments c inner join opportunity o on c.opportunity_id = o.id inner join contact c2 on o.contact_id = c2.id where c2.id = ? and c.is_read = false ", [contact?.id])
        if (opportunityComments.size() > 0)
        {
            status = "0"
        }
        map.status = status
        map.code = "200"
        map.message = "查询成功"
        render(map as JSON)
        return
    }

    @Secured(['permitAll'])
    def appQueryOpportunityFlowsBySerialNumber()
    {
        def json = request.JSON
        println "************************* appQueryOpportunityFlowsBySerialNumber ***************************"
        println json

        def serialNumber = json["serialNumber"]
        String sessionId = json["sessionId"]
        Contact contact = Contact.findByAppSessionId(sessionId)
        if (!sessionId)
        {
            def errors = [errorCode: 4300, errorMessage: "请登录"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        else if (!contact)
        {
            def errors = [errorCode: 4400, errorMessage: "您的账号已在别处登录！如非本人操作，请及时修改密码"]
            render JsonOutput.toJson(errors), status: 400
            return
        }

        if (!serialNumber || serialNumber.size() <= 0)
        {
            def errors = [errorCode: 4262, errorMessage: "订单编号未传"]
            render JsonOutput.toJson(errors), status: 400
            return
        }

        def list = [:]
        /*def flows = []
        def opportunityFlow = [:]
        def opportunity = Opportunity.findBySerialNumber(serialNumber)
        def opportunityFlows = OpportunityFlow.findAll("from OpportunityFlow where opportunity.id = ${opportunity?.id} order by executionSequence ASC")
        def currentFlow = OpportunityFlow.findByOpportunityAndStage(opportunity, opportunity?.stage)
        opportunityFlows.each {
            if (it?.executionSequence < currentFlow?.executionSequence)
            {
                opportunityFlow = [:]
                opportunityFlow.stage = it?.stage?.name
                opportunityFlow.endTime = it?.endTime
                opportunityFlow.flag = 1
                flows.add(opportunityFlow)
            }
            else if (it?.executionSequence == currentFlow?.executionSequence)
            {
                opportunityFlow = [:]
                opportunityFlow.stage = it?.stage?.name
                opportunityFlow.endTime = it?.endTime
                if (opportunity?.status == "Failed")
                {
                    opportunityFlow.flag = 3
                }
                else
                {
                    opportunityFlow.flag = 1
                }
                flows.add(opportunityFlow)
            }
            else
            {
                opportunityFlow = [:]
                opportunityFlow.stage = it?.stage?.name
                opportunityFlow.endTime = it?.endTime
                opportunityFlow.flag = 0
                flows.add(opportunityFlow)
            }
        }*/
        list['opportunityFlow'] = null
        list['serialNumber'] = serialNumber

        println list
        render list as JSON
        return
    }

    @Secured(['permitAll'])
    def appSuggestSubmit()
    {
        //Default3期评房反馈建议提交
        def json = request.JSON
        println "************************* appSuggestSubmit ***************************"
        println json

        String sessionId = json["sessionId"]
        Contact contact = Contact.findByAppSessionId(sessionId)
        if (!sessionId)
        {
            def errors = [errorCode: 4300, errorMessage: "请登录"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        else if (!contact)
        {
            def errors = [errorCode: 4400, errorMessage: "您的账号已在别处登录！如非本人操作，请及时修改密码"]
            render JsonOutput.toJson(errors), status: 400
            return
        }

        def unitPrice = json["unitPrice"]
        def specialX = json["specialX"]
        def memo = json["memo"]

        if (!unitPrice)
        {
            def errors = [errorCode: 4270, errorMessage: "请输入期望单价"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (!specialX)
        {
            def errors = [errorCode: 4271, errorMessage: "请输入特殊因素"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (!memo)
        {
            def errors = [errorCode: 4272, errorMessage: "请输入期望单价"]
            render JsonOutput.toJson(errors), status: 400
            return
        }

        def result = [code: 1000, message: "成功"]
        render JsonOutput.toJson(result), status: 400

    }

    @Secured(['permitAll'])
    def getCityList()
    {
        //
        def cityList = City.findAll()
        render cityList as JSON
    }

    /**
     * 创建日期 2018-05-08
     * 创建人员 齐贝贝
     * 方法功能 企业贷报单功能
     **/
    @Secured(['permitAll'])
    @Transactional
    def businessLoanUpdate()
    {
        println "************************* businessLoanUpdate ***************************"
        def json = request.JSON
        println json

        def sessionId = json["sessionId"]
        def requestedAmount = json["requestedAmount"]
        //借款金额
        def loanDuration = json["loanDuration"]
        //借款期限
        def fullName = json["fullName"].toString()
        //借款人姓名
        def idNumber = json["idNumber"].toString()
        //身份证号
        def cellphone = json["cellphone"]
        //借款人手机号

        Contact contact = Contact.findByAppSessionId(sessionId)
        def opportunity = new Opportunity()

        if (!sessionId)
        {
            def errors = [errorCode: 4300, errorMessage: "请登录"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        else if (!contact)
        {
            def errors = [errorCode: 4400, errorMessage: "您的账号已在别处登录！如非本人操作，请及时修改密码"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        opportunity.contact = contact
        opportunity.user = contact?.user
        opportunity.account = contact?.user?.account

        if (!requestedAmount || !(requestedAmount.matches(/^\d+(\.\d+)*$/)) || Double.parseDouble(requestedAmount) <= 0)
        {
            def errors = [errorCode: 4201, errorMessage: "请输入正确的贷款金额"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (!loanDuration || !(loanDuration.matches(/^[0-9]\d*$/)) || Integer.parseInt(loanDuration) <= 0)
        {
            def errors = [errorCode: 4203, errorMessage: "请输入正确的贷款期限"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (!fullName || !(fullName.matches(/^[\u2190-\u9fff]{1,10}$|^[\dA-Za-z]{1,20}$/)))
        {
            def errors = [errorCode: 4209, errorMessage: "请输入正确的借款人姓名"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (!idNumber || !contactService.verifyIdNumber(idNumber))
        {
            println "4444444444"
            def errors = [errorCode: 4006, errorMessage: "请输入正确的借款人身份证号"]
            render JsonOutput.toJson(errors), status: 400
            return

        }

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss")
        //        def opportunity1 = Opportunity.find("from Opportunity as c where c.idNumber = '${idNumber}' and c.stage not in ('01', '02', '11') and c.status = 'Pending' and c.protectionEndTime > '" + format.format(new Date()) + "'")
        //        if (opportunity1)
        //        {
        //            def errors = [errorCode: 4555, errorMessage: "借款人处于保护期，不允许报单"]
        //            render JsonOutput.toJson(errors), status: 400
        //            return
        //        }
        //        else
        //        {
        Integer protectDays = 10
        if (cellphone)
        {
            protectDays += 5
            if (!(cellphone.matches(/^1\d{10}$/)))
            {
                println "55555555555"
                def errors = [errorCode: 4216, errorMessage: "借款人手机号格式不正确，请重新输入"]
                render JsonOutput.toJson(errors), status: 400
                return
            }
        }
        // 保护期
        Date protectionStartTime = new java.util.Date()
        opportunity.protectionStartTime = protectionStartTime
        opportunity.protectionEndTime = protectionStartTime + protectDays

        opportunity.stage = OpportunityStage.findByCode("231")
        opportunity.type = OpportunityType.findByCode("02")
        opportunity.requestedAmount = requestedAmount.toDouble()
        opportunity.loanDuration = loanDuration.toInteger()
        opportunity.fullName = fullName
        opportunity.cellphone = cellphone
        opportunity.idNumber = idNumber
        opportunity.modifiedDate = new Date()
        if (opportunity.validate())
        {
            opportunity.save flush: true
        }
        else
        {
            println opportunity.errors
        }

        // 借款人信息
        if (opportunity?.idNumber)
        {
            opportunityService.addContacts(opportunity?.fullName, opportunity?.idNumber, opportunity?.cellphone, opportunity?.maritalStatus, "借款人", opportunity)
        }

        opportunityService.assignToClient(opportunity)
        //订单初始化
        opportunityService.initOpportunity(opportunity)

        render opportunity as JSON
        return
        //        }
        //        render opportunity as JSON
        //        return
    }

    /**
     * 创建日期 2018-05-08
     * 创建人员 齐贝贝
     * 方法功能 车贷报单功能
     **/
    @Secured(['permitAll'])
    @Transactional
    def carLoanUpdate()
    {
        println "************************* carLoanUpdate ***************************"
        def json = request.JSON
        println json

        def sessionId = json["sessionId"]
        def requestedAmount = json["requestedAmount"]
        //借款金额
        def loanDuration = json["loanDuration"]
        //借款期限
        def fullName = json["fullName"].toString()
        //借款人姓名
        def idNumber = json["idNumber"].toString()
        //身份证号
        def cellphone = json["cellphone"].toString()
        //借款人手机号
        Contact contact = Contact.findByAppSessionId(sessionId)
        def opportunity = new Opportunity()

        if (!sessionId)
        {
            def errors = [errorCode: 4300, errorMessage: "请登录"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        else if (!contact)
        {
            def errors = [errorCode: 4400, errorMessage: "您的账号已在别处登录！如非本人操作，请及时修改密码"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        opportunity.contact = contact
        opportunity.user = contact?.user
        opportunity.account = contact?.user?.account

        if (!requestedAmount || !(requestedAmount.matches(/^\d+(\.\d+)*$/)) || Double.parseDouble(requestedAmount) <= 0)
        {
            def errors = [errorCode: 4201, errorMessage: "请输入正确的贷款金额"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (!loanDuration || !(loanDuration.matches(/^[0-9]\d*$/)) || Integer.parseInt(loanDuration) <= 0)
        {
            def errors = [errorCode: 4203, errorMessage: "请输入正确的贷款期限"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (!fullName || !(fullName.matches(/^[\u2190-\u9fff]{1,10}$|^[\dA-Za-z]{1,20}$/)))
        {
            def errors = [errorCode: 4209, errorMessage: "请输入正确的借款人姓名"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (!idNumber || !contactService.verifyIdNumber(idNumber))
        {
            println "4444444444"
            def errors = [errorCode: 4006, errorMessage: "请输入正确的借款人身份证号"]
            render JsonOutput.toJson(errors), status: 400
            return

        }

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss")
        def opportunity1 = Opportunity.find("from Opportunity as c where c.idNumber = ? and c.stage not in ('01', '02', '11') and c.status = 'Pending' and c.protectionEndTime > ?", [idNumber, format.format(new Date())])
        //        if (opportunity1)
        //        {
        //            def errors = [errorCode: 4555, errorMessage: "借款人处于保护期，不允许报单"]
        //            render JsonOutput.toJson(errors), status: 400
        //            return
        //        }
        //        else
        //        {
        Integer protectDays = 10
        if (cellphone)
        {
            protectDays += 5
            if (!(cellphone.matches(/^1\d{10}$/)))
            {
                println "55555555555"
                def errors = [errorCode: 4216, errorMessage: "借款人手机号格式不正确，请重新输入"]
                render JsonOutput.toJson(errors), status: 400
                return
            }
        }
        // 保护期
        Date protectionStartTime = new java.util.Date()
        opportunity.protectionStartTime = protectionStartTime
        opportunity.protectionEndTime = protectionStartTime + protectDays

        opportunity.stage = OpportunityStage.findByCode("250")
        opportunity.type = OpportunityType.findByCode("03")
        opportunity.requestedAmount = requestedAmount.toDouble()
        opportunity.loanDuration = loanDuration.toInteger()
        opportunity.fullName = fullName
        opportunity.cellphone = cellphone
        opportunity.idNumber = idNumber
        opportunity.modifiedDate = new Date()
        if (opportunity.validate())
        {
            opportunity.save flush: true
        }
        else
        {
            println opportunity.errors
        }

        // 借款人信息
        if (opportunity?.idNumber)
        {
            opportunityService.addContacts(opportunity?.fullName, opportunity?.idNumber, opportunity?.cellphone, opportunity?.maritalStatus, "借款人", opportunity)
        }

        opportunityService.assignToClient(opportunity)
        //订单初始化
        opportunityService.initOpportunity(opportunity)

        render opportunity as JSON
        return
        //        }
        //        render opportunity as JSON
        //        return
    }

    @Secured(['permitAll'])
    def getUploadToken()
    {
        def token = fileServerService.getUploadToken("hjwooOpportunity/callbackByQiniu")
        render([status: "success", token: token] as JSON)
        return
    }

    @Secured(['permitAll'])
    @Transactional
    def callbackByQiniu()
    {
        println "*********************** hjwooOpportunity  callbackByQiniu  ****************************"
        def json = request.JSON
        println "json:" + json
        String opportunityId = json["opportunityId"]
        String attachmentType = json["type"]
        String fileName = json["fileName"]
        String description = json['description']
        def attachment = new Attachments()
        if (!opportunityId)
        {
            def errors = [errorCode: 5200, errorMessage: "上订单的id不能为空"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (!attachmentType)
        {
            def errors = [errorCode: 5200, errorMessage: "上传图片的类型不能为空"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (!description)
        {
            def errors = [errorCode: 5200, errorMessage: "上传图片的描述不能为空"]
            render JsonOutput.toJson(errors), status: 400
            return
        }

        if (fileName)
        {
            attachment.fileName = "http://quickloanfs.cindata.cn/" + fileName
            attachment.thumbnailUrl = "http://quickloanfs.cindata.cn/" + fileName
            attachment.fileUrl = "http://quickloanfs.cindata.cn/" + fileName

            println "上传图片地址：" + attachment.fileName

            def opportunity = Opportunity.findById(opportunityId)
            attachment.type = AttachmentType.findByName(attachmentType)
            attachment.opportunity = opportunity
            attachment.contact = opportunity?.contact

            def description1 = (description.substring(description.lastIndexOf('/'))).split('/')[1]
            attachment.description = description1.split('\\.')[0]
            //        attachment.description = description.split('\\.')[0]
            if (attachment.validate())
            {
                attachment.save flush: true
                render JsonOutput.toJson([status: 200]), status: 200
                return
            }
            else
            {
                println attachment.errors
                render([errorCode: 5205, errorMsg: "attachments save error"] as JSON)
                return
            }

        }
        else
        {
            def errors = [errorCode: 5205, errorMessage: "调用上传图片服务失败，请稍后重试"]
            render JsonOutput.toJson(errors), status: 400
            return
        }

    }

    @Secured(['permitAll'])
    def queryCurrentAppVersion()
    {
        println "************** client queryCurrentAppVersion******************"
        def json = request.JSON
        println json
        def appName = json['appName']
        def appVersion = AppVersion.find("from AppVersion where appName = '${appName}' order by appVersion DESC")
        if (appVersion)
        {
            render appVersion as JSON
            return
        }
        else
        {
            render ""
            return
        }
    }

    //快手贷匹配产品
    @Secured(['permitAll'])
    def matchProduct()
    {
        println "************** matchProduct******************"
        def json = request.JSON
        println json
        def sessionId = json["sessionId"]
        def productCategory = json['productCategory']
        def minLoanAmount = json['minLoanAmount']?.toDouble()
        def maxLoanAmount = json['maxLoanAmount']?.toDouble()
        def minLoanDuration = json['minLoanDuration']?.toInteger()
        def maxLoanDuration = json['maxLoanDuration']?.toInteger()

        Contact contact = Contact.findByAppSessionId(sessionId)
        if (!sessionId)
        {
            def errors = [errorCode: 4300, errorMessage: "请登录"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        else if (!contact)
        {
            def errors = [errorCode: 4400, errorMessage: "您的账号已在别处登录！如非本人操作，请及时修改密码"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (!productCategory)
        {
            def errors = [errorCode: 4301, errorMessage: "请输入产品类型"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (!minLoanAmount)
        {
            def errors = [errorCode: 4302, errorMessage: "请输入借款最小金额"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (!maxLoanAmount)
        {
            def errors = [errorCode: 4303, errorMessage: "请输入借款最大金额"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (!minLoanDuration)
        {
            def errors = [errorCode: 4304, errorMessage: "请输入借款最小期限"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (!maxLoanDuration)
        {
            def errors = [errorCode: 4305, errorMessage: "请输入借款最大期限"]
            render JsonOutput.toJson(errors), status: 400
            return
        }

        def account = Account.findByName('Default')
        def productAccounts = ProductAccount.findAllByAccount(account)
        def product

        productAccounts?.each {
            if (it?.product?.category?.name == productCategory && it?.product?.active == true)
            {
                def maximumAmount = it?.maximumAmount
                def minimumAmount = it?.minimumAmount
                def minimumDuration = ProductInterest.find("from ProductInterest where product.id = ${it?.id} order by monthesOfStart asc")?.monthesOfStart
                def maximumDuration = ProductInterest.find("from ProductInterest where product.id = ${it?.id} order by monthesOfEnd desc")?.monthesOfEnd
                if (minLoanAmount >= minimumAmount && maxLoanAmount <= maximumAmount && minLoanDuration >= minimumDuration && maxLoanDuration <= maximumDuration)
                {
                    product = it?.product
                }
            }
        }

        if (!product)
        {
            def errors = [errorCode: 4308, errorMessage: "未匹配到任何产品"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        render product as JSON
        return
    }

    //快手贷信用贷结果页
    @Secured(['permitAll'])
    def creditLoan()
    {
    }

    //快手贷抵押贷结果页
    @Secured(['permitAll'])
    def mortgageLoan()
    {
    }

    //快手贷飞钛借呀结果页
    @Secured(['permitAll'])
    def flyTitaniumLoan()
    {
    }

    //快手贷税贷通结果页
    @Secured(['permitAll'])
    def taxCreditLoan()
    {
    }

    @Secured(['permitAll'])
    def appSuggestion()
    {
        println "************** appSuggestion******************"
        def json = request.JSON
        println json
        def sessionId = json["sessionId"]
        def appName = json['appName']
        def type = json['type']
        def description = json['description']

        def fileList = json['fileList']

        Contact contact = Contact.findByAppSessionId(sessionId)
        def appVersion = AppVersion.findByAppName(appName)
        if (!sessionId)
        {
            def errors = [errorCode: 4300, errorMessage: "请登录"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        else if (!contact)
        {
            def errors = [errorCode: 4400, errorMessage: "您的账号已在别处登录！如非本人操作，请及时修改密码"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (!appName)
        {
            def errors = [errorCode: 4401, errorMessage: "请输入App名称"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        else if (!appVersion)
        {
            def errors = [errorCode: 4402, errorMessage: "APP名称不存在"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (!type)
        {
            def errors = [errorCode: 4403, errorMessage: "请输入反馈类型"]
            render JsonOutput.toJson(errors), status: 400
            return
        }
        if (!description)
        {
            def errors = [errorCode: 4404, errorMessage: "请输入反馈意见"]
            render JsonOutput.toJson(errors), status: 400
            return
        }

        def appSuggestion = new AppSuggestion()
        appSuggestion.contact = contact
        appSuggestion.appVersion = appVersion
        appSuggestion.type = type
        appSuggestion.description = description
        appSuggestion.save flush: true

        if (fileList)
        {
            fileList?.each {
                def attachments = new Attachments()
                attachments.appSuggestion = appSuggestion
                attachments.type = AttachmentType.findByName(it?.type)
                attachments.fileName = "http://quickloanfs.cindata.cn/" + it?.fileUrl
                attachments.fileUrl = "http://quickloanfs.cindata.cn/" + it?.fileUrl
                attachments.thumbnailUrl = "http://quickloanfs.cindata.cn/" + it?.fileUrl
                if (attachments.validate())
                {
                    attachments.save flush: true
                }
                else
                {
                    println attachments.errors
                }
            }
        }

        render JsonOutput.toJson([status: 200]), status: 200
    }

    @Secured(['permitAll'])
    def downLoad()
    {

    }
}
